package com.katesoft.scale4j.demo.web;

import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.katesoft.scale4j.common.services.IBeanNameReferences;
import com.katesoft.scale4j.demo.domain.ExchangeRate;
import com.katesoft.scale4j.log.LogFactory;
import com.katesoft.scale4j.log.Logger;
import com.katesoft.scale4j.persistent.client.LocalHibernateDaoSupport;
import com.katesoft.scale4j.persistent.types.RevisionData;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.ui.PopupDateField;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

/** @author kate2007 */
public class XRateApplication extends com.vaadin.Application {
   private static final long serialVersionUID = -1402191185677233251L;
   private static Logger LOGGER = LogFactory.getLogger(XRateApplication.class);
   private static ClassPathXmlApplicationContext context;

   @Override
   public void init() {
      final Window main = new Window("x-rates browser");
      setMainWindow(main);
      setTheme("runo");
      main.addListener(new Window.CloseListener() {
         private static final long serialVersionUID = 4773554836011012867L;

         @Override
         public void windowClose(@SuppressWarnings("unused") Window.CloseEvent e) {
            getMainWindow().getApplication().close();
         }
      });
      if (context == null) {
         context = new ClassPathXmlApplicationContext("META-INF/spring/currencies-app-context.xml");
         context.registerShutdownHook();
      }
      final LocalHibernateDaoSupport hibernateDaoSupport = (LocalHibernateDaoSupport) context
               .getBean(IBeanNameReferences.HIBERNATE_DAO_SUPPORT);
      final Table table = new Table();
      table.setCaption("x-rates");
      table.addContainerProperty("USD", String.class, null);
      table.addContainerProperty("CURRENCY", String.class, null);
      table.addContainerProperty("RATE", String.class, null);
      final Collection<ExchangeRate> currentRates = hibernateDaoSupport.getLocalHibernateTemplate()
               .loadAll(ExchangeRate.class, true);
      renderTable(table, currentRates);
      final PopupDateField datetime = new PopupDateField("Please select the starting time:");
      datetime.setValue(new java.util.Date());
      datetime.setResolution(PopupDateField.RESOLUTION_DAY);
      datetime.addListener(new ValueChangeListener() {
         private static final long serialVersionUID = 2691058453868388815L;

         @Override
         public void valueChange(ValueChangeEvent event) {
            if (event.getProperty().getValue() != null) {
               table.removeAllItems();
               renderTable(
                        table,
                        loadRateForDate(hibernateDaoSupport, (Date) event.getProperty().getValue(),
                                 currentRates));
            }
         }
      });
      datetime.setImmediate(true);
      VerticalLayout verticalLayout = new VerticalLayout();
      verticalLayout.addComponent(datetime);
      verticalLayout.addComponent(table);
      main.addComponent(verticalLayout);
   }

   protected void renderTable(Table table, Collection<ExchangeRate> exchangeRates) {
      for (ExchangeRate rate : exchangeRates) {
         LOGGER.info("USD-%s:=>%s", rate.getCurrency().getCode(), rate.getRate().toString());
         table.addItem(new Object[] { "USD", rate.getCurrency().getCode(),
                  rate.getRate().toString() }, rate.getCurrency().getCode());
      }
      table.setPageLength(exchangeRates.size());
   }

   protected Collection<ExchangeRate> loadRateForDate(LocalHibernateDaoSupport hibernateDaoSupport,
            Date date, Collection<ExchangeRate> currentRates) {
      Collection<Long> uniqueIdentifiers = new LinkedHashSet<Long>();
      Collection<ExchangeRate> rates = new LinkedHashSet<ExchangeRate>();
      for (ExchangeRate currentRate : currentRates) {
         uniqueIdentifiers.add(currentRate.getUniqueIdentifier());
      }
      Collection<RevisionData<ExchangeRate>> values = hibernateDaoSupport.latestRevisionForDate(
               ExchangeRate.class, date, uniqueIdentifiers, "actualDate").values();
      for (RevisionData<ExchangeRate> value : values) {
         rates.add(value.getEntityAtRevision());
      }
      return rates;
   }
}
